package dcutils.rpg.items;

// Import Java JDK Classes
import java.util.LinkedHashMap;

/**
 * This inventory class may represent the inventory of items for sale by an NPC, or a player's inventory.<br/>
 * If the value of an item mapping is null, then there is an infinite number of that item.<br/>
 * @author dca
 */
public class Inventory extends LinkedHashMap<Item, Integer> {
   /** Unique identifier for serialization. */
   private static final long serialVersionUID = 133372210433281812L;

   public Inventory() {
      super(0);
   } // END constructor

   public boolean hasItem(Item item) {
      return containsKey(item);
   } // END hasItem

   public Integer getItemQty(Item item) {
      if(hasItem(item)) {
         // The item is in the inventory.
         return get(item);
      } else {
         // The item is not in the inventory.
         return 0;
      } // END if/else
   } // END getItemQty

   public boolean isQtyInfinite(Item item) {
      if(hasItem(item)) {
         return (null == get(item));
      } else {
         return false;
      } // END if/else
   } // END isQtyInfinite

   public boolean addItem(Item item) {
      return addItem(item, 1);
   } // END addItem

   public boolean addItem(Item item, Integer qty) {
      if(hasItem(item)) {
          // The item is in the inventory.
          if(isQtyInfinite(item)) {
             // The item is infinite within the inventory.
             return false;
          } else {
             // The item is finite, so increment its quantity.
             put(item, get(item) + qty);
             return true;
          } // END if/else
       } else {
          // The item is not in the inventory.
          put(item, qty);
          return true;
       } // END if/else
   } // END addItem

   public boolean removeItem(Item item) {
      return removeItem(item, 1);
   } // END removeItem

   public boolean removeItem(Item item, Integer qty) {
      if(hasItem(item)) {
         // The item is in the inventory.
         if(isQtyInfinite(item)) {
            // The item is infinite within the inventory.
            return false;
         } else if(qty <= get(item)) {
            // There are enough of this item within the inventory.
            put(item, get(item) - qty);
            if(0 == get(item)) remove(item);
            return true;
         } else {
            // There are not enough of this item within the inventory.
            return false;
         } // END if/else
      } else {
         // The item is not in the inventory.
         return false;
      } // END if/else
   } // END removeItem

   @Override
   public String toString() {
      final StringBuffer buffer = new StringBuffer(512 * keySet().size());

      for(Item item : keySet()) {
         if(!buffer.toString().isEmpty()) buffer.append(String.format("%n"));
         buffer.append(String.format("%s (%s)", item, (isQtyInfinite(item) ? "infinite" : get(item))));
      } // END loop

      return buffer.toString();
   } // END toString
  
   @Override
   public boolean equals(Object obj) {
      if(null == obj) {
         return false;
      } else if(obj instanceof Inventory) {
    	  Inventory stats = (Inventory)obj;

         return super.equals(stats);
      } else {
         return false;
      } // END if/else
   } // END equals

   @Override
   public int hashCode() {
      int hashCode = 101;
      hashCode = (11 * hashCode) + super.hashCode();
      return hashCode;
   } // END hashCode
} // END class Inventory
